package com.yuanda.erp9.syn.util;

import com.yuanda.erp9.syn.entity.CmsBrandsTempEntity;
import com.yuanda.erp9.syn.entity.CmsSuppliersTempEntity;
import com.yuanda.erp9.syn.enums.CachePrefixEnum;
import com.yuanda.erp9.syn.pojo.CmsGoodsPojo;
import com.yuanda.erp9.syn.service.erp9.BrandService;
import com.yuanda.erp9.syn.service.erp9.SupplierService;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @ClassName CacheUtil
 * @Description 自定缓存工具
 * @Date 2022/11/18
 * @Author myq
 */
@Slf4j
@Component
public class CacheUtil extends BeanAutowiredHelper {
    // key = 表名 value = cache对象
    protected static ConcurrentHashMap<String, Cache> tableCache = new ConcurrentHashMap<>();

    // key = 表名 value = ObjectCache对象
    protected static ConcurrentHashMap<String, ObjectCache> objectCache = new ConcurrentHashMap<>();

    protected static BrandService brandService;
    protected static SupplierService supplierService;

    private static final Object object = new Object();

    @PostConstruct
    public void init() {
        brandService = super.getBrandService();
        supplierService = super.getSupplierService();
    }

    /**
     * @Description: 同一个表名返回同一个一个cache对象
     * @Params:
     * @Return:
     * @Author: Mr.myq
     * @Date: 2022/11/23 17:04
     */
    public static Cache init(String tableName) {
        synchronized (object) {
            if (!tableCache.containsKey(tableName)) {
                Cache cache = new Cache(tableName);
                tableCache.put(tableName, cache);
                return cache;
            } else {
                return tableCache.get(tableName);
            }
        }
    }

    /**
     * 根据表明获取ObjectCatch对象
     * @param tableName 表明
     * @return 返回ObjectCatch对象
     */
    public static ObjectCache objectInit(String tableName) {
        synchronized (object) {
            if (!objectCache.containsKey(tableName)) {
                ObjectCache cache = new ObjectCache(tableName);
                objectCache.put(tableName, cache);
                return cache;
            } else {
                return objectCache.get(tableName);
            }
        }
    }

    /**
     * @Description: cache用来缓存单张表数据
     * @Params:
     * @Return:
     * @Author: Mr.myq
     * @Date: 2022/11/2317:18
     */
    public static class Cache extends CacheUtil {

        private String tableName;

        public Cache(String tableName) {
            this.tableName = tableName;
        }

        /**
         * 缓存
         */
        public ConcurrentHashMap<String, Integer> filedCache = new ConcurrentHashMap<>();
        /**
         * 缓存可用
         */
        public volatile boolean cacheIsValid = false;

        /**
         * @Description: put
         * @Params:
         * @Return:
         * @Author: Mr.myq
         * @Date: 2022/11/1816:50
         */
        public void put(String k, Integer v) {
            k = k.toLowerCase().trim();
            filedCache.put(k, v);
        }

        /**
         * @Description: putall
         * @Params:
         * @Return:
         * @Author: Mr.myq
         * @Date: 2022/11/2410:55
         */
        public void putAll(Map<String, Integer> map) {
            filedCache.putAll(map);
        }

        /**
         * @Description: get(可以使用 。 但不推荐) 直接返回，需要自己维护缓存信息
         * @Params:
         * @Return:
         * @Author: Mr.myq
         * @Date: 2022/11/1816:50
         */
        public Integer get(String k) {
            waiting();
            k = k.toLowerCase().trim();
            return filedCache.get(k);
        }

        /**
         * @Description: 等待初始化完成
         * @Params:
         * @Return:
         * @Author: Mr.myq
         * @Date: 2023/1/515:58
         */
        public void waiting() {
            while (!cacheIsValid) {
            }
        }


        /**
         * @Description: insertAndGet 自动维护缓存信息
         * @Params:
         * @Return:
         * @Author: Mr.myq
         * @Date: 2022/11/1816:50
         */
        public Integer insertAndGet(Object entity) {
            // 防止获取到未初始化的完整对象
            synchronized (object) {
                // 等待缓存初始化完成
                waiting();
                CmsBrandsTempEntity brandsTempEntity = null;
                CmsSuppliersTempEntity suppliersTempEntity = null;
                String nameKey = null;
                if (entity instanceof CmsBrandsTempEntity) {
                    brandsTempEntity = (CmsBrandsTempEntity) entity;
                    nameKey = brandsTempEntity.getName();
                } else if (entity instanceof CmsSuppliersTempEntity) {
                    suppliersTempEntity = (CmsSuppliersTempEntity) entity;
                    nameKey = suppliersTempEntity.getName();
                } else {
                    throw new IllegalArgumentException("非法类格式化异常");
                }
                // 小写
                nameKey = nameKey.toLowerCase().trim();
                // 定制化操作
                if("weidmüller".equals(nameKey)){
                    nameKey = "WEIDMULLER".toLowerCase().trim();
                }
                if (!filedCache.containsKey(nameKey)) {
                    try {
                        // 同步数据
                        if (CachePrefixEnum.BRAND.getKey().equals(tableName)) {
                            assert brandsTempEntity != null : "brandsTempEntity参数不能为空";
                            brandService.insert(brandsTempEntity);
                            this.put(brandsTempEntity.getName(), brandsTempEntity.getBrandid());
                        } else if (CachePrefixEnum.SUPPLIERS.getKey().equals(tableName)) {
                            assert suppliersTempEntity != null : "suppliersTempEntity参数不能为空";
                            supplierService.insert(suppliersTempEntity);
                            this.put(suppliersTempEntity.getName(), suppliersTempEntity.getSupplierid());
                        } else {
                            log.warn("缓存同步告警：tableName:{},key:{}", tableName, "");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        throw new RuntimeException("同步缓存数据异常:" + e);
                    }
                }
                return filedCache.get(nameKey);
            }

        }
    }

    /**
     * @Description: cache用来缓存单张表数据
     * @Params:
     * @Return:
     * @Author: Mr.myq
     * @Date: 2022/11/2317:18
     */
    public static class ObjectCache extends CacheUtil {
        private String tableName;

        public ObjectCache(String tableName) {
            this.tableName = tableName;
        }

        /**
         * 缓存
         */
        public ConcurrentHashMap<String, Object> filedCache = new ConcurrentHashMap<>();

        /**
         * 缓存可用
         */
        public volatile boolean cacheIsValid = false;

        /**
         * @Description: put
         * @Params:
         * @Return:
         * @Author: Mr.myq
         * @Date: 2022/11/1816:50
         */
        public void put(String k, Object v) {
            filedCache.put(k, v);
        }

        /**
         * @Description: putall
         * @Params:
         * @Return:
         * @Author: Mr.myq
         * @Date: 2022/11/2410:55
         */
        public void putAll(Map<String, Object> map) {
            filedCache.putAll(map);
        }

        /**
         * @Description: putall
         * @Params:
         * @Return:
         * @Author: Mr.myq
         * @Date: 2022/11/2410:55
         */
        public void delAll() {
            filedCache.clear();
        }

        /**
         * @Description: get(可以使用 。 但不推荐) 直接返回，需要自己维护缓存信息
         * @Params:
         * @Return:
         * @Author: Mr.myq
         * @Date: 2022/11/1816:50
         */
        public Object get(String k) {
            waiting();
            return filedCache.get(k);
        }

        /**
         * 删除
         * @param k
         */
        public  void del(String k){
            filedCache.remove(k);
        }
        
        /**
         * @Description: 等待初始化完成
         * @Params:
         * @Return:
         * @Author: Mr.myq
         * @Date: 2023/1/515:58
         */
        public void waiting() {
            while (!cacheIsValid) {
            }
        }
    }
}

/**
 * @Description: 帮助子类静态方法初始化子类
 * @Params:
 * @Return:
 * @Author: Mr.myq
 * @Date: 2022/11/2917:36
 */
@Getter
@Setter
class BeanAutowiredHelper {

    @Autowired
    protected BrandService brandService;

    @Autowired
    protected SupplierService supplierService;

}



